﻿#pragma once

#include "precomp.h"
#include "game_object.h"
#include "global_state.h"
#include "bullet.h"
#include "bonus.h"
#include "effect.h"
#include "renders.h"
#include "enemy.h"
#include "replay.h"
#include "ring_renderer.h"
#include "background.h"

class Enemy;
struct Replay_Frame;

class Player : public GameObject{
public:
	Player();
	~Player();
	
	CL_Vec2<float> direction;
	float normal_speed;
	float focused_speed;
	float spellcard_active_speed;

	float wind_radius;
	float wind_current_radius;
	float wind_speed;
	float wind_accel;

	float bonus_collision_size;
	float bonus_attract_collision;
	float bonus_attract_focus_collision;
	float graze_collision_size;

	bool focused;
	bool spellcard_activated; // включён ли режим спеллкарты
	bool wind_activated;
	float wind_time;
	bool is_bomb;
	float bomb_time;
	int spellcard; // текущая спеллкарта
	bool dead;
	int invicible;

	void Shoot(int bullet_type);

	CL_Sprite player_sprite;
	CL_Sprite focus_sprite;
	CL_Sprite wind_sprite;
	CL_Sprite wind_font_sprite;
	CL_Sprite *dead_splash;
	CL_Sprite *magic_flash;
	CL_Size visible_size;

	// Статистика
	int lives;
	int spells;
	unsigned int score;
	unsigned int power;
	unsigned int points;
	unsigned int spell_time;
	unsigned int graze;
	int spell_time_remaining;
	int hp;
	int base_hp;
	int spell_failed; // Триггер взятия спеллкарты
	int graze_score;

	float wind;
	float wind_gain_speed;
	float wind_shot_gain;
	float wind_kill_gain;
	float wind_graze_gain;
	float wind_to_blow;
	float wind_blow_time;
	float wind_max_blow_time;

	unsigned int spellcard_min_duration;
	unsigned int spellcard_max_duration;
	unsigned int start_power;
	float bomb_duration;
	float bomb_damage;

	// Анимация
	float player_time;
	float dead_time;
	float death_time; // сколько длится анимация смерти
	int invicible_time; // сколько всего будет в неуязвимости
	int focused_time; // для плавного включения-выключения фокуса
	float spellcard_time; // время с начала активации спеллкарты
	int moving_aside; // движение вбок
	int last_move_direction;
	float sidemove_time;
	// === TO DO ===

	// Параметры стрельбы и спеллкарт
	bool shooting; // выстрел
	float shot_gaining; // время непрерывного нажатия кнопки выстрела
	float time_to_activate_wind; // время от нажатия кнопки до начала активации ветра
	float time_wind_activation; // время активации ветра
	bool rapid; // непрерывный выстрел
	bool spellcard_trigger; // активация спеллкарты(бомба)
	bool spellcard_change; // смена спеллкарты
	bool wind_trigger;
	bool bomb_trigger;
	float shooting_speed;
	float focus_speed;
	CL_Angle focus_angle;
	float time_from_last_shot;
	float time_from_last_autoshot1;
	float shooting_time;
	float bullet_alpha;

	// Выстрел обычный
	float shot1_interval;
	float shot1_speed;
	unsigned int shot1_bullets;
	unsigned int shot1_damage;
	unsigned int shot1_focus_damage;
	// Дополнительные пули к обычному выстрелу
	float shot2_interval;
	float shot2_speed;
	unsigned int shot2_bullets;
	unsigned int shot2_damage;
	unsigned int shot2_startpower;
	unsigned int shot2_steppower;
	// Спеллкарта "Перекрестье"
	// --- Автопули
	float shot3_interval;
	float shot3_speed;
	float shot3_angle_speed;
	float shot3_accel_time;
	float shot3_speed_delta;
	unsigned int shot3_bullets;
	unsigned int shot3_damage;
	// --- Наводимые пули
	float shot4_shooting_speed;
	float shot4_interval;
	float shot4_speed;
	float shot4_angle_speed;
	float shot4_change_angle;
	float shot4_speed_delta;
	float shot4_radius;
	unsigned int shot4_bullets;
	unsigned int shot4_damage;

	Enemy* dummy_player;

	void AttachInput(CL_DisplayWindow &window);

	void LoadPlayer(CL_String name, CL_GraphicContext &gc, CL_ResourceManager &resources);

	void Render(CL_GraphicContext &gc);
	void RenderBack(CL_GraphicContext &gc, RingSprite* ring_renderer);
	void Update(float time);
	void UpdateFromReplay(Replay_Frame &rf);
	void CalculateCollisions();
	void BlowWind(float radius, float time);
	void BlowBomb(float time);
	void Reset(int power_reset=0);
	void DropBonus();
private:
	// Обработчики для ввода
	bool joystick_available;
	void on_key_down(const CL_InputEvent &key, const CL_InputState &state);
	void on_key_up(const CL_InputEvent &key, const CL_InputState &state);
	void on_joystick_axis_move(const CL_InputEvent &joy, const CL_InputState &state);
	void on_joystick_key_down(const CL_InputEvent &joy, const CL_InputState &state);
	void on_joystick_key_up(const CL_InputEvent &joy, const CL_InputState &state);

	CL_SlotContainer slots;

	CL_InputDevice keyboard;
	CL_InputDevice joystick;

	int last_key_up;
	int last_key_down;
	int last_key_left;
	int last_key_right;
	int joystick_moved;

	void process_keyboard();
	void process_joystick();
};

extern Player player;
